"""
---------------------------------------------------------------------
- File: exceptions.py
- Date: 2025/7/10
- Author: yangzhide
- Email: xxzjyzd@126.com
- Description: 全局异常处理
---------------------------------------------------------------------
"""

from fastapi import FastAPI, Request

# 数据校验
from fastapi.exceptions import RequestValidationError

# HTTPException
from starlette.exceptions import HTTPException as StarletteHTTPException

from app.common import app_response


class BaseException(Exception):
    """基础异常类"""

    def __init__(code: int | str, self, message: str):
        self.message = message
        self.code = code
        super().__init__(message)


# ---全局异常处理---


async def business_exception_handle(request: Request, exc: BaseException):
    """
    捕获自定义的业务异常
    """
    return app_response.fail(code=exc.code, msg=exc.message, status_code=200)


async def validation_exception_handle(request: Request, exc: RequestValidationError):
    """
    捕获请求参数校验异常
    """
    first_error = exc.errors()[0]
    field = ".".join(str(loc) for loc in first_error["loc"])
    return app_response.fail(
        code=422,
        msg=f"请求参数校验失败：字段【{field}】,信息:{first_error['msg']}",
        status_code=422,
    )


# --- HTTPException ---
async def http_exception_handle(request: Request, exc: StarletteHTTPException):
    """
    捕获HTTP异常
    """
    if exc.status_code == 401:
        return app_response.fail(
            code=exc.status_code,
            msg=exc.detail,  # 认证失败
            status_code=exc.status_code,
        )
    if exc.status_code == 403:
        return app_response.fail(
            code=exc.status_code,
            msg=exc.detail,  # 认证成功，无权访问
            status_code=exc.status_code,
        )

    # 其他 HTTPException 按原样返回
    return app_response.fail(
        msg=exc.detail, code=exc.status_code, status_code=exc.status_code
    )


# ---其他异常---
async def global_exception_handle(request: Request, exc: Exception):
    """
    捕获其他异常
    """
    return app_response.fail(code=201, msg=str(exc), status_code=200)


# --- 统一注册函数 ---
def register_exception_handlers(app: FastAPI):
    """
    异常处理器注册到FastAPI实例中
    """
    app.add_exception_handler(BaseException, business_exception_handle)
    app.add_exception_handler(RequestValidationError, validation_exception_handle)
    app.add_exception_handler(StarletteHTTPException, http_exception_handle)
    app.add_exception_handler(Exception, global_exception_handle)
    print("全局异常处理器注册完成")
